/*******************************************************************************
 FileName:      newMemPool.h
 Author:        urey
 Version :      1.0
 Date:          2015年7月9日
 Description:
 History:
 <author>		<time>			<version >      <desc>
 urey        2015年7月9日          1.0          create
 *******************************************************************************/
#ifndef NEWMEMPOOL_H_
#define NEWMEMPOOL_H_

#include "../apr_Lib/include/apr_general.h"
#include "../apr_Lib/include/apr_pools.h"
#include "../apr_Lib/include/apr_thread_mutex.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

typedef unsigned int    Uint32;
typedef int             Int32;
typedef unsigned short	Uint16;
typedef unsigned char   Uint8;
typedef enum
{
    MEMPOOL_SUCCESS = 0,
    MEMPOOL_NULL_ERROR
}MemPool_status;

typedef struct MemPoolNode_ MemPoolNode;
typedef struct MemPoolHead_ MemPoolHead;
typedef struct MemPool_     MemPool;
typedef char*               MemSpace_t;
#define S_MemPoolHeader      MemPool

struct MemPoolNode_
{
    struct MemPoolNode_*    pNextNode;
    struct MemPoolNode_*    pPrevNode;
    MemPoolHead*            pMemPoolHead;
    Uint32                  check;
};

#define NODEHEADSIZE  sizeof(MemPoolNode)

struct MemPoolHead_
{
    apr_pool_t*             pApr_pool;
    struct MemPoolHead_*    pPrevHead;
    struct MemPoolHead_*    pNextHead;
    MemPoolNode             FreeMemHead;
    MemPoolNode             UsedMemHead;
    Uint32                  maxAvil;
    Uint32                  itemAvil;
    Uint16                  nodeSize;
    apr_thread_mutex_t*     pHeadMutex;  /* 保障spaceNode分配和释放的线程安全 */
};

struct MemPool_
{
    MemPoolHead MemPoolHeader;
    apr_pool_t* pApr_pool;
};

/* 用于内存块校验的全局码，如果内存块中的校验码与全局码不一致，则可能内存出现错误 */
extern Uint32 gMemPoolCheck;

/**
 * 内存池初始化接口
 * @param ppMemPool  内存池的二维指针，用于返回一个内存池的空间
 * @param pParent    为当前内存池的Apr_pool指定一个父pool
 * @return
 */
MemPool_status initMemPool(MemPool** ppMemPool, apr_pool_t* pParent);

/**
 * 内存池空间分配接口，在当前的内存池中预分配一定的空间
 * @param pMemPool  当前的内存池结构指针
 * @param itemSize  需要分配的块大小
 * @param itemNum   需要分配的块数量
 * @return
 */
MemPool_status newMemPool(MemPool* pMemPool, Uint16 itemSize, Int32 itemNum);
#define newMemoryPool(pMemPool, itemSize, itemNum)  newMemPool(pMemPool, itemSize, itemNum)

/**
 * 用于打印当前内存池信息
 * @param pMemPool
 */
void dumpMemPool(MemPool* pMemPool);
#define dumpMemoryPool(pMemPool)    dumpMemPool(pMemPool);
/**
 * 从内存池中申请一片大小为spaceSize的空间
 * @param pMemPool
 * @param spaceSize
 * @return
 */
MemSpace_t memAlloc(MemPool* pMemPool, Uint16 spaceSize);

/**
 * 释放从内存池中获取的空间
 * @param pSpace
 * @return
 * @warning     只能释放从内存池中获取的空间
 */
MemPool_status memFree(MemSpace_t pSpace);

#ifdef __cplusplus
}       /* extern "C" */
#endif /* __cplusplus */
#endif /* NEWMEMPOOL_H_ */
